package safeCommitter.test.executor.builder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.junit.runner.Request;
import org.testng.xml.XmlClass;

import safeCommitter.model.TestType;

/**
 * @author Luiz Henrique Rolim
 * 
 * Holds a List of Tests to be run , either JUNIT or TESTNG, that were found
 * from the search.
 * 
 */
public class SCTestBuilder {

	private final Set<Request> junitRequests = new HashSet<Request>();

	private final List<XmlClass> testNGClasses = new ArrayList<XmlClass>();

	private final Map<String, List<String>> testNGclazzMap = new HashMap<String, List<String>>();

	public SCTestBuilder(final String[] testsFoundFromSearch) {

		for (String test : testsFoundFromSearch) {
			String[] parts = test.split(":");
			if (TestType.JUNIT.name().equalsIgnoreCase(parts[0])) {
				incJunit(parts[1], parts[2]);
			} else if (TestType.TESTNG.name().equalsIgnoreCase(parts[0])) {
				incTestNG(parts[1], parts[2]);
			}
		}
		buildTestNGXml();

	}

	private void buildTestNGXml() {
		for (String clazzName : testNGclazzMap.keySet()) {
			try {
				Class<?> c = Class.forName(clazzName);
				XmlClass clazz = new XmlClass(c);
				clazz.getIncludedMethods().addAll(testNGclazzMap.get(clazzName));
				testNGClasses.add(clazz);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}

	}

	void incTestNG(final String clazzName, final String methodName) {
		if (!testNGclazzMap.containsKey(clazzName)) {
			List<String> methodList = new ArrayList<String>();
			methodList.add(methodName);
			testNGclazzMap.put(clazzName, methodList);
		} else {
			testNGclazzMap.get(clazzName).add(methodName);
		}

	}

	private void incJunit(final String clazzName, final String methodName) {
		try {
			Class<?> clazz = Class.forName(clazzName);
			Request request;
			if (!methodName.equals("")) {
				request = Request.method(clazz, methodName);
			} else {
				request = Request.aClass(clazz);
			}
			junitRequests.add(request);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}

	public Set<Request> getJunitTests() {
		return junitRequests;
	}

	public List<XmlClass> getTestNGClasses() {
		return testNGClasses;
	}

}
